from rmasm.translaters import mlog
from rmasm.translaters.macro_move_command import *
from rmasm.exceptions import *

# ======================
#      赋值命令转换器
# ======================


# key 是 左值 和 右值 类型的元组
# 参数是 左值 和 右值
move_command_translators: Dict[Tuple[Type, Type], Callable[[Word, Word], str]] = {}


def move_command_translator(left_type, right_type):
    def wrapper(func):
        move_command_translators[(left_type, right_type)] = func
        return func

    return wrapper


@move_command_translator(Memory, Value)
def mvct_write(l: Memory, r: Value) -> str:
    return f'write {r.value} {l.block} {l.offset}'


@move_command_translator(Value, Memory)
def mvct_read(l: Value, r: Memory) -> str:
    return f'read {l.value} {r.block} {r.offset}'


@move_command_translator(Value, Value)
def mvct_set(l: Value, r: Value) -> str:
    return f'set {l.value} {r.value}'


@move_command_translator(Value, Sensor)
def mvct_sensor(l: Value, r: Sensor) -> str:
    return f'sensor {l.value} {r.unit} {r.value}'


@move_command_translator(Value, BinaryOperation)
def mvct_bo(l: Value, r: BinaryOperation) -> str:
    if r.name not in mlog.binaryOperatorMap:
        raise TranslateException("未知的二元运算符：" + str(r.name))
    op = mlog.binaryOperatorMap[r.name]
    return f'op {op} {l.value} {r.left} {r.right}'


@move_command_translator(Value, UnaryOperation)
def mvct_uo(l: Value, r: UnaryOperation) -> str:
    if r.name not in mlog.unaryOperatorMap:
        raise TranslateException("未知的一元运算符：" + str(r.name))
    op = mlog.unaryOperatorMap[r.name]
    return f'op {op} {l.value} {r.value}'


@move_command_translator(Value, Macro)
def mvct_macro(l: Value, r: Macro) -> str:
    if r.name not in macro_move_command_translators:
        raise TranslateException("未知的取值宏：" + r.name)
    return macro_move_command_translators[r.name](l.value, r)
